﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Diagnostics;
using SimpleIR;

namespace InterpreterCore
{
	/// <summary>
	/// Alass representing a memory location in the program. Possible types of memory locations are: 
	/// (1) Objects allocated on the heap.
	/// (2) Fixed storage locations for locals and globals.
	/// </summary>
	internal abstract class CLocation
	{
		/// <summary>
		/// The type that this location contains.
		/// </summary>
		internal readonly IRType LocationType;

		/// <summary>
		/// The position of this location in the memory.
		/// </summary>
		protected int m_locationaddress;

		protected CLocation(int address, IRType loctype)
		{
			Debug.Assert(loctype != null);

			this.LocationType = loctype;
			this.m_locationaddress = address;
		}

		/// <summary>
		/// Get the address of the location
		/// </summary>
		internal int Address
		{ get { return this.m_locationaddress; } }

		/// <summary>
		/// Enumerate all the pointer/ref target addresses (the enclosing object for references) that are refered to from this location.
		/// NULL and UNINITIALZED pointers/references are returned as having addresses equal to -1
		/// </summary>
		internal abstract IEnumerable<int> EnumerateTrgtAddresses();

		/// <summary>
		/// Output a string that represents the location
		/// </summary>
		internal abstract string DebuggerString();

		/// <summary>
		/// Serialize the location for the heap dump
		/// </summary>
		internal abstract void SerializeForHeapDump(System.IO.TextWriter dumpstr);

		/// <summary>
		/// Serialize the location for DGML display
		/// </summary>
		internal abstract void SerializeForDGMLDisplay(System.Xml.XmlWriter nodexw, System.Xml.XmlWriter edgexw, string lname);

		/// <summary>
		/// Read a ptr from the given offset in this location.
		/// </summary>
		internal abstract PtrValue ReadPassablePtrValueFrom(ReferenceValue rf);

		/// <summary>
		/// Write a ptr to the given offset in this location.
		/// </summary>
		internal abstract void StorePassablePtrValTo(PtrValue pv, ReferenceValue rf);

		/// <summary>
		/// Read a numeric value from the given offset in this location.
		/// </summary>
		internal abstract NumericValue ReadPassableNumericFrom(ReferenceValue rf);

		/// <summary>
		/// Write a numeric value to the given offset in this location.
		/// </summary>
		internal abstract void StorePassableNumericValTo(NumericValue nv, ReferenceValue rf);

		/// <summary>
		/// Read a composite (struct) value from the given offset in this location.
		/// </summary>
		internal abstract CompositeValueEntry[] ReadCompositeFrom(ReferenceValue rf);

		/// <summary>
		/// Write a composite (struct) value to the given offset in this location.
		/// </summary>
		internal abstract void StoreCompositeTo(CompositeValueEntry[] cv, ReferenceValue rf);
	}
}

